//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2022 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

import Foundation
import SotoCore

extension SsmSap {
    // MARK: Enums

    public enum ApplicationStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case activated = "ACTIVATED"
        case deleting = "DELETING"
        case failed = "FAILED"
        case registering = "REGISTERING"
        case starting = "STARTING"
        case stopped = "STOPPED"
        case stopping = "STOPPING"
        case unknown = "UNKNOWN"
        public var description: String { return self.rawValue }
    }

    public enum ApplicationType: String, CustomStringConvertible, Codable, _SotoSendable {
        case hana = "HANA"
        public var description: String { return self.rawValue }
    }

    public enum ComponentStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case activated = "ACTIVATED"
        public var description: String { return self.rawValue }
    }

    public enum ComponentType: String, CustomStringConvertible, Codable, _SotoSendable {
        case hana = "HANA"
        public var description: String { return self.rawValue }
    }

    public enum CredentialType: String, CustomStringConvertible, Codable, _SotoSendable {
        case admin = "ADMIN"
        public var description: String { return self.rawValue }
    }

    public enum DatabaseStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case running = "RUNNING"
        case starting = "STARTING"
        case stopped = "STOPPED"
        case unknown = "UNKNOWN"
        case warning = "WARNING"
        public var description: String { return self.rawValue }
    }

    public enum DatabaseType: String, CustomStringConvertible, Codable, _SotoSendable {
        case system = "SYSTEM"
        case tenant = "TENANT"
        public var description: String { return self.rawValue }
    }

    public enum HostRole: String, CustomStringConvertible, Codable, _SotoSendable {
        case leader = "LEADER"
        case standby = "STANDBY"
        case unknown = "UNKNOWN"
        case worker = "WORKER"
        public var description: String { return self.rawValue }
    }

    public enum OperationStatus: String, CustomStringConvertible, Codable, _SotoSendable {
        case error = "ERROR"
        case inprogress = "INPROGRESS"
        case success = "SUCCESS"
        public var description: String { return self.rawValue }
    }

    public enum PermissionActionType: String, CustomStringConvertible, Codable, _SotoSendable {
        case restore = "RESTORE"
        public var description: String { return self.rawValue }
    }

    // MARK: Shapes

    public struct Application: AWSDecodableShape {
        public let appRegistryArn: String?
        public let arn: String?
        public let components: [String]?
        public let id: String?
        public let lastUpdated: Date?
        public let status: ApplicationStatus?
        public let statusMessage: String?
        public let type: ApplicationType?

        public init(appRegistryArn: String? = nil, arn: String? = nil, components: [String]? = nil, id: String? = nil, lastUpdated: Date? = nil, status: ApplicationStatus? = nil, statusMessage: String? = nil, type: ApplicationType? = nil) {
            self.appRegistryArn = appRegistryArn
            self.arn = arn
            self.components = components
            self.id = id
            self.lastUpdated = lastUpdated
            self.status = status
            self.statusMessage = statusMessage
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case appRegistryArn = "AppRegistryArn"
            case arn = "Arn"
            case components = "Components"
            case id = "Id"
            case lastUpdated = "LastUpdated"
            case status = "Status"
            case statusMessage = "StatusMessage"
            case type = "Type"
        }
    }

    public struct ApplicationCredential: AWSEncodableShape & AWSDecodableShape {
        public let credentialType: CredentialType
        public let databaseName: String
        public let secretId: String

        public init(credentialType: CredentialType, databaseName: String, secretId: String) {
            self.credentialType = credentialType
            self.databaseName = databaseName
            self.secretId = secretId
        }

        public func validate(name: String) throws {
            try self.validate(self.databaseName, name: "databaseName", parent: name, max: 100)
            try self.validate(self.databaseName, name: "databaseName", parent: name, min: 1)
            try self.validate(self.secretId, name: "secretId", parent: name, max: 100)
            try self.validate(self.secretId, name: "secretId", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case credentialType = "CredentialType"
            case databaseName = "DatabaseName"
            case secretId = "SecretId"
        }
    }

    public struct ApplicationSummary: AWSDecodableShape {
        public let arn: String?
        public let id: String?
        public let tags: [String: String]?
        public let type: ApplicationType?

        public init(arn: String? = nil, id: String? = nil, tags: [String: String]? = nil, type: ApplicationType? = nil) {
            self.arn = arn
            self.id = id
            self.tags = tags
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "Arn"
            case id = "Id"
            case tags = "Tags"
            case type = "Type"
        }
    }

    public struct Component: AWSDecodableShape {
        public let applicationId: String?
        public let componentId: String?
        public let componentType: ComponentType?
        public let databases: [String]?
        public let hosts: [Host]?
        public let lastUpdated: Date?
        public let primaryHost: String?
        public let status: ComponentStatus?

        public init(applicationId: String? = nil, componentId: String? = nil, componentType: ComponentType? = nil, databases: [String]? = nil, hosts: [Host]? = nil, lastUpdated: Date? = nil, primaryHost: String? = nil, status: ComponentStatus? = nil) {
            self.applicationId = applicationId
            self.componentId = componentId
            self.componentType = componentType
            self.databases = databases
            self.hosts = hosts
            self.lastUpdated = lastUpdated
            self.primaryHost = primaryHost
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId = "ApplicationId"
            case componentId = "ComponentId"
            case componentType = "ComponentType"
            case databases = "Databases"
            case hosts = "Hosts"
            case lastUpdated = "LastUpdated"
            case primaryHost = "PrimaryHost"
            case status = "Status"
        }
    }

    public struct ComponentSummary: AWSDecodableShape {
        public let applicationId: String?
        public let componentId: String?
        public let componentType: ComponentType?
        public let tags: [String: String]?

        public init(applicationId: String? = nil, componentId: String? = nil, componentType: ComponentType? = nil, tags: [String: String]? = nil) {
            self.applicationId = applicationId
            self.componentId = componentId
            self.componentType = componentType
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId = "ApplicationId"
            case componentId = "ComponentId"
            case componentType = "ComponentType"
            case tags = "Tags"
        }
    }

    public struct Database: AWSDecodableShape {
        public let applicationId: String?
        public let arn: String?
        public let componentId: String?
        public let credentials: [ApplicationCredential]?
        public let databaseId: String?
        public let databaseName: String?
        public let databaseType: DatabaseType?
        public let lastUpdated: Date?
        public let primaryHost: String?
        public let sqlPort: Int?
        public let status: DatabaseStatus?

        public init(applicationId: String? = nil, arn: String? = nil, componentId: String? = nil, credentials: [ApplicationCredential]? = nil, databaseId: String? = nil, databaseName: String? = nil, databaseType: DatabaseType? = nil, lastUpdated: Date? = nil, primaryHost: String? = nil, sqlPort: Int? = nil, status: DatabaseStatus? = nil) {
            self.applicationId = applicationId
            self.arn = arn
            self.componentId = componentId
            self.credentials = credentials
            self.databaseId = databaseId
            self.databaseName = databaseName
            self.databaseType = databaseType
            self.lastUpdated = lastUpdated
            self.primaryHost = primaryHost
            self.sqlPort = sqlPort
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId = "ApplicationId"
            case arn = "Arn"
            case componentId = "ComponentId"
            case credentials = "Credentials"
            case databaseId = "DatabaseId"
            case databaseName = "DatabaseName"
            case databaseType = "DatabaseType"
            case lastUpdated = "LastUpdated"
            case primaryHost = "PrimaryHost"
            case sqlPort = "SQLPort"
            case status = "Status"
        }
    }

    public struct DatabaseSummary: AWSDecodableShape {
        public let applicationId: String?
        public let arn: String?
        public let componentId: String?
        public let databaseId: String?
        public let databaseType: DatabaseType?
        public let tags: [String: String]?

        public init(applicationId: String? = nil, arn: String? = nil, componentId: String? = nil, databaseId: String? = nil, databaseType: DatabaseType? = nil, tags: [String: String]? = nil) {
            self.applicationId = applicationId
            self.arn = arn
            self.componentId = componentId
            self.databaseId = databaseId
            self.databaseType = databaseType
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId = "ApplicationId"
            case arn = "Arn"
            case componentId = "ComponentId"
            case databaseId = "DatabaseId"
            case databaseType = "DatabaseType"
            case tags = "Tags"
        }
    }

    public struct DeleteResourcePermissionInput: AWSEncodableShape {
        public let actionType: PermissionActionType?
        public let resourceArn: String
        public let sourceResourceArn: String?

        public init(actionType: PermissionActionType? = nil, resourceArn: String, sourceResourceArn: String? = nil) {
            self.actionType = actionType
            self.resourceArn = resourceArn
            self.sourceResourceArn = sourceResourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(.+:){2,4}.+$|^arn:(.+:){1,3}.+\\/.+$")
            try self.validate(self.sourceResourceArn, name: "sourceResourceArn", parent: name, pattern: "^arn:(.+:){2,4}.+$|^arn:(.+:){1,3}.+\\/.+$")
        }

        private enum CodingKeys: String, CodingKey {
            case actionType = "ActionType"
            case resourceArn = "ResourceArn"
            case sourceResourceArn = "SourceResourceArn"
        }
    }

    public struct DeleteResourcePermissionOutput: AWSDecodableShape {
        public let policy: String?

        public init(policy: String? = nil) {
            self.policy = policy
        }

        private enum CodingKeys: String, CodingKey {
            case policy = "Policy"
        }
    }

    public struct DeregisterApplicationInput: AWSEncodableShape {
        public let applicationId: String

        public init(applicationId: String) {
            self.applicationId = applicationId
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationId, name: "applicationId", parent: name, pattern: "^[\\w\\d]{1,50}$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId = "ApplicationId"
        }
    }

    public struct DeregisterApplicationOutput: AWSDecodableShape {
        public init() {}
    }

    public struct GetApplicationInput: AWSEncodableShape {
        public let applicationArn: String?
        public let applicationId: String?

        public init(applicationArn: String? = nil, applicationId: String? = nil) {
            self.applicationArn = applicationArn
            self.applicationId = applicationId
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationArn, name: "applicationArn", parent: name, pattern: "^arn:(.+:){2,4}.+$|^arn:(.+:){1,3}.+\\/.+$")
            try self.validate(self.applicationId, name: "applicationId", parent: name, pattern: "^[\\w\\d]{1,50}$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationArn = "ApplicationArn"
            case applicationId = "ApplicationId"
        }
    }

    public struct GetApplicationOutput: AWSDecodableShape {
        public let application: Application?
        public let tags: [String: String]?

        public init(application: Application? = nil, tags: [String: String]? = nil) {
            self.application = application
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case application = "Application"
            case tags = "Tags"
        }
    }

    public struct GetComponentInput: AWSEncodableShape {
        public let applicationId: String
        public let componentId: String

        public init(applicationId: String, componentId: String) {
            self.applicationId = applicationId
            self.componentId = componentId
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationId, name: "applicationId", parent: name, pattern: "^[\\w\\d]{1,50}$")
            try self.validate(self.componentId, name: "componentId", parent: name, pattern: "^[\\w\\d-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId = "ApplicationId"
            case componentId = "ComponentId"
        }
    }

    public struct GetComponentOutput: AWSDecodableShape {
        public let component: Component?

        public init(component: Component? = nil) {
            self.component = component
        }

        private enum CodingKeys: String, CodingKey {
            case component = "Component"
        }
    }

    public struct GetDatabaseInput: AWSEncodableShape {
        public let applicationId: String?
        public let componentId: String?
        public let databaseArn: String?
        public let databaseId: String?

        public init(applicationId: String? = nil, componentId: String? = nil, databaseArn: String? = nil, databaseId: String? = nil) {
            self.applicationId = applicationId
            self.componentId = componentId
            self.databaseArn = databaseArn
            self.databaseId = databaseId
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationId, name: "applicationId", parent: name, pattern: "^[\\w\\d]{1,50}$")
            try self.validate(self.componentId, name: "componentId", parent: name, pattern: "^[\\w\\d-]+$")
            try self.validate(self.databaseArn, name: "databaseArn", parent: name, pattern: "^arn:(.+:){2,4}.+$|^arn:(.+:){1,3}.+\\/.+$")
            try self.validate(self.databaseId, name: "databaseId", parent: name, pattern: "[\\w\\d]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId = "ApplicationId"
            case componentId = "ComponentId"
            case databaseArn = "DatabaseArn"
            case databaseId = "DatabaseId"
        }
    }

    public struct GetDatabaseOutput: AWSDecodableShape {
        public let database: Database?
        public let tags: [String: String]?

        public init(database: Database? = nil, tags: [String: String]? = nil) {
            self.database = database
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case database = "Database"
            case tags = "Tags"
        }
    }

    public struct GetOperationInput: AWSEncodableShape {
        public let operationId: String

        public init(operationId: String) {
            self.operationId = operationId
        }

        public func validate(name: String) throws {
            try self.validate(self.operationId, name: "operationId", parent: name, pattern: "^[{]?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[}]?$")
        }

        private enum CodingKeys: String, CodingKey {
            case operationId = "OperationId"
        }
    }

    public struct GetOperationOutput: AWSDecodableShape {
        public let operation: Operation?

        public init(operation: Operation? = nil) {
            self.operation = operation
        }

        private enum CodingKeys: String, CodingKey {
            case operation = "Operation"
        }
    }

    public struct GetResourcePermissionInput: AWSEncodableShape {
        public let actionType: PermissionActionType?
        public let resourceArn: String

        public init(actionType: PermissionActionType? = nil, resourceArn: String) {
            self.actionType = actionType
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(.+:){2,4}.+$|^arn:(.+:){1,3}.+\\/.+$")
        }

        private enum CodingKeys: String, CodingKey {
            case actionType = "ActionType"
            case resourceArn = "ResourceArn"
        }
    }

    public struct GetResourcePermissionOutput: AWSDecodableShape {
        public let policy: String?

        public init(policy: String? = nil) {
            self.policy = policy
        }

        private enum CodingKeys: String, CodingKey {
            case policy = "Policy"
        }
    }

    public struct Host: AWSDecodableShape {
        public let hostIp: String?
        public let hostName: String?
        public let hostRole: HostRole?
        public let instanceId: String?

        public init(hostIp: String? = nil, hostName: String? = nil, hostRole: HostRole? = nil, instanceId: String? = nil) {
            self.hostIp = hostIp
            self.hostName = hostName
            self.hostRole = hostRole
            self.instanceId = instanceId
        }

        private enum CodingKeys: String, CodingKey {
            case hostIp = "HostIp"
            case hostName = "HostName"
            case hostRole = "HostRole"
            case instanceId = "InstanceId"
        }
    }

    public struct ListApplicationsInput: AWSEncodableShape {
        public let maxResults: Int?
        public let nextToken: String?

        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^.{16,1024}$")
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListApplicationsOutput: AWSDecodableShape {
        public let applications: [ApplicationSummary]?
        public let nextToken: String?

        public init(applications: [ApplicationSummary]? = nil, nextToken: String? = nil) {
            self.applications = applications
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case applications = "Applications"
            case nextToken = "NextToken"
        }
    }

    public struct ListComponentsInput: AWSEncodableShape {
        public let applicationId: String?
        public let maxResults: Int?
        public let nextToken: String?

        public init(applicationId: String? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.applicationId = applicationId
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationId, name: "applicationId", parent: name, pattern: "^[\\w\\d]{1,50}$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^.{16,1024}$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId = "ApplicationId"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListComponentsOutput: AWSDecodableShape {
        public let components: [ComponentSummary]?
        public let nextToken: String?

        public init(components: [ComponentSummary]? = nil, nextToken: String? = nil) {
            self.components = components
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case components = "Components"
            case nextToken = "NextToken"
        }
    }

    public struct ListDatabasesInput: AWSEncodableShape {
        public let applicationId: String?
        public let componentId: String?
        public let maxResults: Int?
        public let nextToken: String?

        public init(applicationId: String? = nil, componentId: String? = nil, maxResults: Int? = nil, nextToken: String? = nil) {
            self.applicationId = applicationId
            self.componentId = componentId
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationId, name: "applicationId", parent: name, pattern: "^[\\w\\d]{1,50}$")
            try self.validate(self.componentId, name: "componentId", parent: name, pattern: "^[\\w\\d-]+$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, pattern: "^.{16,1024}$")
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId = "ApplicationId"
            case componentId = "ComponentId"
            case maxResults = "MaxResults"
            case nextToken = "NextToken"
        }
    }

    public struct ListDatabasesOutput: AWSDecodableShape {
        public let databases: [DatabaseSummary]?
        public let nextToken: String?

        public init(databases: [DatabaseSummary]? = nil, nextToken: String? = nil) {
            self.databases = databases
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case databases = "Databases"
            case nextToken = "NextToken"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn"))
        ]

        public let resourceArn: String

        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(.+:){2,4}.+$|^arn:(.+:){1,3}.+\\/.+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        public let tags: [String: String]?

        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct Operation: AWSDecodableShape {
        public let endTime: Date?
        public let id: String?
        public let lastUpdatedTime: Date?
        public let properties: [String: String]?
        public let resourceArn: String?
        public let resourceId: String?
        public let resourceType: String?
        public let startTime: Date?
        public let status: OperationStatus?
        public let statusMessage: String?
        public let type: String?

        public init(endTime: Date? = nil, id: String? = nil, lastUpdatedTime: Date? = nil, properties: [String: String]? = nil, resourceArn: String? = nil, resourceId: String? = nil, resourceType: String? = nil, startTime: Date? = nil, status: OperationStatus? = nil, statusMessage: String? = nil, type: String? = nil) {
            self.endTime = endTime
            self.id = id
            self.lastUpdatedTime = lastUpdatedTime
            self.properties = properties
            self.resourceArn = resourceArn
            self.resourceId = resourceId
            self.resourceType = resourceType
            self.startTime = startTime
            self.status = status
            self.statusMessage = statusMessage
            self.type = type
        }

        private enum CodingKeys: String, CodingKey {
            case endTime = "EndTime"
            case id = "Id"
            case lastUpdatedTime = "LastUpdatedTime"
            case properties = "Properties"
            case resourceArn = "ResourceArn"
            case resourceId = "ResourceId"
            case resourceType = "ResourceType"
            case startTime = "StartTime"
            case status = "Status"
            case statusMessage = "StatusMessage"
            case type = "Type"
        }
    }

    public struct PutResourcePermissionInput: AWSEncodableShape {
        public let actionType: PermissionActionType
        public let resourceArn: String
        public let sourceResourceArn: String

        public init(actionType: PermissionActionType, resourceArn: String, sourceResourceArn: String) {
            self.actionType = actionType
            self.resourceArn = resourceArn
            self.sourceResourceArn = sourceResourceArn
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(.+:){2,4}.+$|^arn:(.+:){1,3}.+\\/.+$")
            try self.validate(self.sourceResourceArn, name: "sourceResourceArn", parent: name, pattern: "^arn:(.+:){2,4}.+$|^arn:(.+:){1,3}.+\\/.+$")
        }

        private enum CodingKeys: String, CodingKey {
            case actionType = "ActionType"
            case resourceArn = "ResourceArn"
            case sourceResourceArn = "SourceResourceArn"
        }
    }

    public struct PutResourcePermissionOutput: AWSDecodableShape {
        public let policy: String?

        public init(policy: String? = nil) {
            self.policy = policy
        }

        private enum CodingKeys: String, CodingKey {
            case policy = "Policy"
        }
    }

    public struct RegisterApplicationInput: AWSEncodableShape {
        public let applicationId: String
        public let applicationType: ApplicationType
        public let credentials: [ApplicationCredential]
        public let instances: [String]
        public let sapInstanceNumber: String?
        public let sid: String?
        public let tags: [String: String]?

        public init(applicationId: String, applicationType: ApplicationType, credentials: [ApplicationCredential], instances: [String], sapInstanceNumber: String? = nil, sid: String? = nil, tags: [String: String]? = nil) {
            self.applicationId = applicationId
            self.applicationType = applicationType
            self.credentials = credentials
            self.instances = instances
            self.sapInstanceNumber = sapInstanceNumber
            self.sid = sid
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationId, name: "applicationId", parent: name, pattern: "^[\\w\\d]{1,50}$")
            try self.credentials.forEach {
                try $0.validate(name: "\(name).credentials[]")
            }
            try self.validate(self.credentials, name: "credentials", parent: name, max: 20)
            try self.validate(self.credentials, name: "credentials", parent: name, min: 1)
            try self.instances.forEach {
                try validate($0, name: "instances[]", parent: name, pattern: "^i-[\\w\\d]{8}$|^i-[\\w\\d]{17}$")
            }
            try self.validate(self.instances, name: "instances", parent: name, max: 1)
            try self.validate(self.instances, name: "instances", parent: name, min: 1)
            try self.validate(self.sapInstanceNumber, name: "sapInstanceNumber", parent: name, pattern: "^[0-9]{2}$")
            try self.validate(self.sid, name: "sid", parent: name, pattern: "^[A-Z][A-Z0-9]{2}$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 1)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId = "ApplicationId"
            case applicationType = "ApplicationType"
            case credentials = "Credentials"
            case instances = "Instances"
            case sapInstanceNumber = "SapInstanceNumber"
            case sid = "Sid"
            case tags = "Tags"
        }
    }

    public struct RegisterApplicationOutput: AWSDecodableShape {
        public let application: Application?
        public let operationId: String?

        public init(application: Application? = nil, operationId: String? = nil) {
            self.application = application
            self.operationId = operationId
        }

        private enum CodingKeys: String, CodingKey {
            case application = "Application"
            case operationId = "OperationId"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn"))
        ]

        public let resourceArn: String
        public let tags: [String: String]

        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(.+:){2,4}.+$|^arn:(.+:){1,3}.+\\/.+$")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, min: 1)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case tags
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        public static var _encoding = [
            AWSMemberEncoding(label: "resourceArn", location: .uri("resourceArn")),
            AWSMemberEncoding(label: "tagKeys", location: .querystring("tagKeys"))
        ]

        public let resourceArn: String
        /// Adds/updates or removes credentials for applications registered with AWS Systems Manager for SAP.
        public let tagKeys: [String]

        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:(.+:){2,4}.+$|^arn:(.+:){1,3}.+\\/.+$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, pattern: "^(?!aws:)[a-zA-Z+-=._:/]+$")
            }
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateApplicationSettingsInput: AWSEncodableShape {
        public let applicationId: String
        public let credentialsToAddOrUpdate: [ApplicationCredential]?
        public let credentialsToRemove: [ApplicationCredential]?

        public init(applicationId: String, credentialsToAddOrUpdate: [ApplicationCredential]? = nil, credentialsToRemove: [ApplicationCredential]? = nil) {
            self.applicationId = applicationId
            self.credentialsToAddOrUpdate = credentialsToAddOrUpdate
            self.credentialsToRemove = credentialsToRemove
        }

        public func validate(name: String) throws {
            try self.validate(self.applicationId, name: "applicationId", parent: name, pattern: "^[\\w\\d]{1,50}$")
            try self.credentialsToAddOrUpdate?.forEach {
                try $0.validate(name: "\(name).credentialsToAddOrUpdate[]")
            }
            try self.validate(self.credentialsToAddOrUpdate, name: "credentialsToAddOrUpdate", parent: name, max: 20)
            try self.validate(self.credentialsToAddOrUpdate, name: "credentialsToAddOrUpdate", parent: name, min: 1)
            try self.credentialsToRemove?.forEach {
                try $0.validate(name: "\(name).credentialsToRemove[]")
            }
            try self.validate(self.credentialsToRemove, name: "credentialsToRemove", parent: name, max: 20)
            try self.validate(self.credentialsToRemove, name: "credentialsToRemove", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case applicationId = "ApplicationId"
            case credentialsToAddOrUpdate = "CredentialsToAddOrUpdate"
            case credentialsToRemove = "CredentialsToRemove"
        }
    }

    public struct UpdateApplicationSettingsOutput: AWSDecodableShape {
        public let message: String?
        public let operationIds: [String]?

        public init(message: String? = nil, operationIds: [String]? = nil) {
            self.message = message
            self.operationIds = operationIds
        }

        private enum CodingKeys: String, CodingKey {
            case message = "Message"
            case operationIds = "OperationIds"
        }
    }
}

// MARK: - Errors

/// Error enum for SsmSap
public struct SsmSapErrorType: AWSErrorType {
    enum Code: String {
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize SsmSap
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    public static var conflictException: Self { .init(.conflictException) }
    public static var internalServerException: Self { .init(.internalServerException) }
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    public static var validationException: Self { .init(.validationException) }
}

extension SsmSapErrorType: Equatable {
    public static func == (lhs: SsmSapErrorType, rhs: SsmSapErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension SsmSapErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
